package com.sinosoft.builder.parser;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.sinosoft.builder.config.BusinessConceptHelper;
import com.sinosoft.builder.templates.concept.BusinessConcept;

/**
 * XML解析的枚举类
 * 
 * @since 1.0 2010-7-13
 * @author 潘巍（Peter Pan）
 * 
 */
public enum SinoParserType {
	// 应用模型
	APP("com.sinosoft.builder.templates.app", "apptemplate", "app", null),

	// 视图模型
	VIEW("com.sinosoft.builder.templates.view", "viewtemplate", "view", null) {

		/**
		 * 通过额外信息验证文档合法性<br>
		 * 1.验证bindid和layout属性是否父子关系；<br>
		 * 2.验证bindin属性对应的scene的place属性是否为该元素；<br>
		 * 3.验证start属性是否对应的是子的structure；<br>
		 */
		@Override
		public List<String> validation(List<?> o) {
			return super.validation(o);
		}

		@Override
		public List<String> validationOne(Object o) {
			return super.validationOne(o);
		}
	},

	// 业务概念模型
	BUSSINESSCONCEPT("com.sinosoft.builder.templates.businessconcept",
			"businessconcept/BusinessConcept", "concept", null) {
		@Override
		public List<String> validationOne(Object o) {
			BusinessConcept bc = (BusinessConcept) o;
			return BusinessConceptHelper.validationBusinessConcept(bc);
		}

		@Override
		public <T> List<T> parser() {
			return parser(null);
		}

		@SuppressWarnings("unchecked")
		@Override
		public <T> List<T> parser(List<String> errs) {
			try {
				List<T> rtn = new ArrayList<T>();
				T t = (T) BusinessConceptHelper
						.parseBussinessConcept(BUSSINESSCONCEPT);
				if (t != null)
					rtn.add(t);
				return rtn;
			} catch (IOException e) {
				logger.severe("解析业务概念模型出现错误");
			}
			return null;
		}
	},

	// 业务概念-实体概念模型
	BUSSINESSCONCEPT_ENTITY("com.sinosoft.builder.templates.concept",
			"concept/part/EntityConcept", "concept/EntityConcept", null),
	// 业务概念-角色概念模型
	BUSSINESSCONCEPT_ROLE("com.sinosoft.builder.templates.concept",
			"concept/part/RoleConcept", "concept/RoleConcept", null),
	// 业务概念-行为概念模型
	BUSSINESSCONCEPT_BEHAVIOR("com.sinosoft.builder.templates.concept",
			"concept/part/BehaviorConcept", "concept/BehaviorConcept", null),
	// 业务概念-关联领域概念模型
	BUSSINESSCONCEPT_ASSOCIATIONCONCEPTDOMAIN(
			"com.sinosoft.builder.templates.concept",
			"concept/part/AssociationConceptBetweenDomainConcepts",
			"concept/AssociationConceptBetweenDomainConcepts", null),
	// 业务概念-行为规范概念模型
	BUSSINESSCONCEPT_BEHAVIORCRITERION(
			"com.sinosoft.builder.templates.concept",
			"concept/part/BehaviorCriterionConcept",
			"concept/BehaviorCriterionConcept", null),
	// 业务概念-场景概念模型
	BUSSINESSCONCEPT_SCENE("com.sinosoft.builder.templates.concept",
			"concept/part/SceneConcept", "concept/SceneConcept", null),
	// 业务概念-代码表概念模型
	BUSSINESSCONCEPT_CODESET("com.sinosoft.builder.templates.concept",
			"concept/part/CodeSet", "concept/CodeSet", null),
	// 业务概念-文档概念模型
	BUSSINESSCONCEPT_DOCUMENT("com.sinosoft.builder.templates.concept",
			"concept/part/DocumentConfig", "concept/DocumentConfig", null),
	// 业务概念-查询表单模型
	BUSSINESSCONCEPT_SEARCHFORM("com.sinosoft.builder.templates.concept",
			"concept/part/SearchFormConfig", "concept/SearchFormConfig", null),

	// 业务概念-文档存储模型
	DOCUMENT_STORAGE("com.sinosoft.builder.templates.concept.docStorage",
			"concept/DocumentStorage", null, null);

	private static final Logger logger = Logger.getLogger(SinoParserType.class
			.getName());

	private final String jaxbFactoryPackage;

	private final String schemaFileName;

	private final String xmlFileNameOrPath;

	/**
	 * 文件过滤器，按照扩展名来过滤
	 */
	private final String[] exts;

	private final static String META_RESOURCE_PATH = "META-INF/schema/";

	private final static String DATA_RESOURCE_PATH = "META-INF/metadata/";

	SinoParserType(String jaxbFactoryPackage, String schemaFileName,
			String xmlDirectoryPath, String[] exts) {
		this.jaxbFactoryPackage = jaxbFactoryPackage;
		String[] schemaFileNameArr = schemaFileName.split(",");
		StringBuffer schemaFileNameSB = new StringBuffer();
		for (String s : schemaFileNameArr) {
			schemaFileNameSB.append(META_RESOURCE_PATH);
			schemaFileNameSB.append(s);
			schemaFileNameSB.append(".xsd,");
		}
		this.schemaFileName = schemaFileNameSB.toString().substring(0,
				schemaFileNameSB.length() - 1);

		if (xmlDirectoryPath != null) {
			this.xmlFileNameOrPath = DATA_RESOURCE_PATH + xmlDirectoryPath;
		} else {
			this.xmlFileNameOrPath = null;
		}

		this.exts = exts;
	}

	public String getJaxbFactoryPackage() {
		return jaxbFactoryPackage;
	}

	public String getSchemaFileName() {
		return schemaFileName;
	}

	public String getXmlFileNameOrPath() {
		return xmlFileNameOrPath;
	}

	public boolean accept(File f) {
		boolean rtn = false;
		if (this.exts != null && this.exts.length > 0) {
			for (String ext : this.exts) {
				rtn = f.getName().toLowerCase().endsWith("." + ext);
				if (rtn)
					return true;
			}
		}
		rtn = f.getName().toLowerCase().endsWith(".xml");
		return rtn;
	}

	public List<String> validation(List<?> os) {
		if (os != null) {
			List<String> rtn = new ArrayList<String>();
			for (Object o : os) {
				List<String> l = validationOne(o);
				if (l != null)
					rtn.addAll(l);
			}
			return rtn;
		}
		return null;
	}

	public List<String> validationOne(Object o) {
		return null;
	}

	public <T> List<T> parser() {
		return parser(null);
	}

	public <T> List<T> parser(List<String> errs) {
		try {
			return (new SinoParser<T>()).parse(this, errs);
		} catch (IOException e) {
			logger.severe("解析出现错误");
		}
		return null;
	}

}
